/**
 * \file   node.h
 * \author Babinot Alexandre, Guilet Pierre
 *  \version 1.0
 *  \date 24 janvier 2012
 */
#ifndef NODE_H
#define NODE_H
#include<vector>
#include "pNode.h"
template<class T>
class pNode;

/**
 *\class Node
 *
 * \brief classe permettant de representer un noeud
 */
template<class T>
class Node
{
typedef typename std::vector<pNode<T>*>::iterator ItePNode;
private:
    std::vector<pNode<T>*> pNodesVector_;

//on en aura besoin si on veut remonter une valeur à un noeud connu. Une valeur nulle = racine.
    Node<T> * parent;
//iterator sur le pNode du père contenant le pointeur vers ce node.
    typename std::vector<pNode<T>*>::iterator iteToPositionPnodeParent;
    int hauteur;
    int nbK;


public:
    /**
     * \fn Node(pNode<T>* pNode)
     *  \brief Constructeur d'un nouveau Noeud
     *  \param pNode valeur de départ du noeud
     */
    Node(pNode<T>* pNode);
    /**
     * \fn getLastPNode()
     *  \brief récupère le dernier PNode
     *  \return le dernier PNode
     */
     pNode<T>* getLastPNode();
    /**
     * \fn add(pNode<T>* i)
     *  \brief ajout d'une clé
     *  \param pNode valeur du noeud à insérer
     */
    void add(pNode<T> * i);
     /**
     * \fn addFirst(pNode<T>* i)
     *  \brief ajout au début du noeud
     *  \param pNode valeur du noeud à insérer
     */
    void addFirst(pNode<T> * i);
     /**
     * \fn addLast(pNode<T>* i)
     *  \brief ajout à la fin du noeud
     *  \param pNode valeur du noeud à insérer
     */
    void addLast(pNode<T> * i);
    /**
     * \fn getPNodesVector()
     *  \brief retourne le vecteur contenant les valeurs du noeud
     *  \return retourne le vecteur contenant les valeurs du noeud
     */
    typename std::vector<pNode<T>*>& getPNodesVector();
    /**
     * \fn getIteToPositionPnodeParent()
     *  \brief retourne la postion dans le parent à laquelle le noeud courant est lié 
     *  \return retourne la postion dans le parent à laquelle le noeud courant est lié 
     */
    typename std::vector<pNode<T>*>::iterator getIteToPositionPnodeParent();
     /**
     * \fn addLast(int index,T key)
     *  \brief ajout une valeur à un index
     *  \param index index où insérer la valeur
     *  \param key clé à insérer
     */    
    void addNodeToIndex(int index,T key);
    /**
     * \fn getParent()
     *  \brief retourne le parent du noeud
     *  \return retourne le parent du noeud
     */    
    Node<T> * getParent();
    /**
     * \fn setParent(Node<T> * n)
     *  \brief actualise le parent du noeud
     *  \param n nouveau parent
     */  
    void setParent(Node<T> * n);
    /**
     * \fn deleteKey(T key,typename std::vector<pNode<T>*>::iterator it)
     *  \brief supprime la clé à l'itérateur it
     *  \param key clé à supprimer
     *  \param it postion de la clé
     */  
    void deleteKey(typename std::vector<pNode<T>*>::iterator it);
    /**
     * \fn getNbk()
     *  \brief retourne le nombre de clé du noeud
     *  \return retourne le nombre de clé du noeud
     */  
    unsigned int getNbK();

};

#include<iostream>
using namespace std;
template<class T>
Node<T>::Node(pNode<T>* newPNode)
{
    nbK=1;
    this->pNodesVector_.push_back(newPNode);
    pNode<T>* pNodeEmpty = new pNode<T>((T)-1);
    this->pNodesVector_.push_back(pNodeEmpty);
    parent=NULL;
}

template<class T>
void Node<T>::add(pNode<T> * newPNode)
{
    this->pNodesVector_.push_back(newPNode);
    nbK++;
}

template<class T>
pNode<T>* Node<T>::getLastPNode()
{
    ItePNode it = pNodesVector_.begin();

    while(it!=pNodesVector_.end())
    {
        ++it;
    }
    --it;
    --it;

    return *it;
}

template<class T>
void Node<T>::addFirst(pNode<T> * newPNode)
{
    this->pNodesVector_.insert(pNodesVector_.begin(),newPNode);
    nbK++;
}

template<class T>
void Node<T>::addLast(pNode<T> * newPNode)
{
    this->pNodesVector_.insert(pNodesVector_.end()-2,newPNode);
    nbK++;
}

template<class T>
vector<pNode<T>*>& Node<T>::getPNodesVector()
{
    return this->pNodesVector_;
}

template<class T>
void Node<T>::addNodeToIndex(int index,T key)
{
    pNode<T>* newPNode= new pNode<T>(key);
    typename vector<pNode<T>*>::iterator it;
    it = this->pNodesVector_.begin();
    this->pNodesVector_.insert(it+index,newPNode);
    nbK++;
    iteToPositionPnodeParent = it+index;
}

template<class T>
unsigned int Node<T>::getNbK()
{
    return nbK;

}

template<class T>
typename std::vector<pNode<T>*>::iterator Node<T>::getIteToPositionPnodeParent()
{
    bool trouve = 0;
    ItePNode it = parent->getPNodesVector().begin();

    while((!(it==parent->getPNodesVector().end()))&&!trouve)
    {
        if(this==(*it)->getPointeur()){
            trouve=1;
        }else{
            ++it;
        }



    }

    return it;

}

template<class T>
Node<T>* Node<T>::getParent()
{
    return parent;

}

template<class T>
void Node<T>::setParent(Node<T>* n)
{
    parent=n;

}

template<class T>
void Node<T>::deleteKey(typename std::vector<pNode<T>*>::iterator it)
{
    this->pNodesVector_.erase(it);
    //delete node r;
    nbK--;
}


#endif
